﻿Imports System.Text
Imports System.Windows.Input

Namespace Microsoft.VisualStudio.RegularExpression
	Friend Class KeyTypeConverter
		Inherits System.Windows.Input.KeyConverter
		Public Overrides Overloads Function CanConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal destinationType As Type) As Boolean
			If ((destinationType IsNot GetType(Char)) OrElse (context Is Nothing)) OrElse (context.Instance Is Nothing) Then
				Return MyBase.CanConvertTo(context, destinationType)
			End If

            Dim instance = CType(context.Instance, Key)
			Return instance >= Key.None AndAlso instance <= Key.OemClear
		End Function

		Public Overrides Overloads Function ConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As Type) As Object
			If destinationType Is GetType(Char) AndAlso value IsNot Nothing Then
                Dim myKey = MyBase.ConvertToString(value)

                If (Not String.IsNullOrEmpty(myKey)) AndAlso myKey.Length = 1 Then
                    If Char.IsLetter(myKey, 0) Then
                        Return If(IsShiftKeyDown(), myKey.ToUpper()(0), myKey.ToLower()(0))
                    ElseIf Char.IsDigit(myKey, 0) AndAlso (Not IsShiftKeyDown()) Then
                        Return myKey.Chars(0)
                    End If
                End If

                Select Case CType(value, Key)
                    Case Key.Oem4
                        Return If(IsShiftKeyDown(), "{"c, "["c)
                    Case Key.Oem6
                        Return If(IsShiftKeyDown(), "}"c, "]"c)
                    Case Key.Oem5
                        Return If(IsShiftKeyDown(), "|"c, "\"c)
                    Case Key.D1
                        Return "!"c
                    Case Key.D2
                        Return "@"c
                    Case Key.D3
                        Return "#"c
                    Case Key.D4
                        Return "$"c
                    Case Key.D5
                        Return "%"c
                    Case Key.D6
                        Return "^"c
                    Case Key.D7
                        Return "&"c
                    Case Key.D8
                        Return "*"c
                    Case Key.D9
                        Return "("c
                    Case Key.D0
                        Return ")"c
                    Case Key.Space
                        Return " "c
                    Case Key.OemMinus
                        Return If(IsShiftKeyDown(), "_"c, "-"c)
                    Case Key.OemPlus
                        Return If(IsShiftKeyDown(), "+"c, "="c)
                    Case Key.OemQuestion
                        Return If(IsShiftKeyDown(), "?"c, "/"c)
                    Case Key.OemSemicolon
                        Return If(IsShiftKeyDown(), ":"c, ";"c)
                    Case Key.Oem7
                        Return If(IsShiftKeyDown(), """"c, "'"c)
                    Case Key.OemPeriod
                        Return If(IsShiftKeyDown(), ">"c, "."c)
                    Case Key.OemComma
                        Return If(IsShiftKeyDown(), "<"c, ","c)
                End Select

				Return Nothing
			Else
				Return MyBase.ConvertTo(context, culture, value, destinationType)
			End If
		End Function

		Public Function ConvertToChar(ByVal key As Key) As Char?
            Dim result = ConvertTo(key, GetType(Char))
			If result IsNot Nothing Then
				Return CChar(result)
			End If

			Return Nothing
		End Function

		Private Function IsShiftKeyDown() As Boolean
			Return Keyboard.IsKeyDown(Key.RightShift) OrElse Keyboard.IsKeyDown(Key.LeftShift)
		End Function
	End Class
End Namespace